#include "Game.h"

IGame* createGame( HINSTANCE hInst, HWND hWnd )
{
	return new Game( hInst, hWnd );
}

Game::Game( HINSTANCE hInst, HWND hWnd ) :
	m_input( hInst, hWnd )
{
	// initialize camera
	m_camera.hand = Camera::RIGHTHANDED;

	m_camera.eye = float3( 0, 0, 20.f );
	m_camera.at  = float3( 0, 0, 0 );
	m_camera.up  = float3( 0, 1, 0 );

	m_camera.projectionType = Camera::PERSPECTIVE_FOV;
	m_camera.perspectiveFov.fovy = D3DXToRadian(45.f);
	m_camera.perspectiveFov.aspect = 1024.f/768.f;

	m_camera.zn = 1.0f;
	m_camera.zf = 100.0f;

	// initialize ship control
	m_player.setInput( m_input );

	// initialize ship's polygon and color
	m_polygon.push_back( float3( 0, 1.f, 0 ) );
	m_polygon.push_back( float3( -0.2f, -0.5f, 0 ) );
	m_polygon.push_back( float3( +0.2f, -0.5f, 0 ) );

	m_color = float4( 1.f, 0.2f, 0.1f, 0.1f );

	// initialize bodies of water
	poly::Polygon water;
	water.push_back( float3( +1.f, 1.f, 0 ) );
	water.push_back( float3( -1.f, 1.f, 0 ) );
	water.push_back( float3( 0, -1.f, 0 ) );

	m_waterPolygons.push_back( water );


	// initialize buoyancy constraint
	m_buoyancy.forceDensity = float3( 0, 1.f, 0 );
	m_buoyancy.bodies.insert( &m_player );
	for( int i = 0; i < m_waterPolygons.size(); i++ )
		m_buoyancy.buoyant.insert( & m_waterPolygons[i] );

	// set water color
	m_waterColor = float4( 1.f, 0.9f, 0.3f, 0.3f );

	// add player to dynamics
	m_dynamics.dynObjects.insert( &m_player );
	
	// add buoyancy to dynamics
	m_dynamics.constraints.insert( &m_buoyancy );
}

Game::~Game()
{
	m_waterPolyViews.clear();
	m_d3dDevice = 0;
}

void Game::onCreateGraphics( D3DDevice device )
{
	m_d3dDevice = device;

	m_d3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	float44 world = identity44();
	float44 view = m_camera.view();
	float44 proj = m_camera.projection();

	m_d3dDevice->SetTransform( D3DTS_WORLD, &world );
	m_d3dDevice->SetTransform( D3DTS_VIEW, &view );
	m_d3dDevice->SetTransform( D3DTS_PROJECTION, &proj );

	// initialize player graphics
	m_player.setup( m_d3dDevice, m_polygon, m_color );

	// initialize water polygon views
	m_waterPolyViews.resize( m_waterPolygons.size() );
	for( int i = 0; i < m_waterPolyViews.size(); i++ )
	{
		m_waterPolyViews[i].initialize( m_d3dDevice );
		m_waterPolyViews[i].setup( m_waterPolygons[i], m_waterColor );
	}
}

void Game::onResetGraphics( D3DDevice device )
{
	m_d3dDevice = device;

	m_d3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	float44 view = m_camera.view();
	float44 proj = m_camera.projection();

	m_d3dDevice->SetTransform( D3DTS_VIEW, &view );
	m_d3dDevice->SetTransform( D3DTS_PROJECTION, &proj );
}

void Game::onLostGraphics()
{
}

void Game::onFrameMove(float dt)
{
	m_dynamics.step(dt);
}

void Game::onFrameRender(float dt)
{
	for( int i = 0; i < m_waterPolyViews.size(); i++ )
		m_waterPolyViews[i].render( identity44() );
	m_dynamics.render(dt);
}

void Game::onDestroyGraphics()
{
}
